<?php

/**
 * static lass for exception handling and loggin
 *
 * @since 2010-06-02
 * @author Daniel Niedergesäß <daniel.niedergesaess@googlemail.com>
 * @version $Id$
 */
final class Core_Exceptionhandler {

    /**
     * private constructor cause static class
     */
    private function __construct() {

    }

    /**
     * init exceptionhandler
     */
    public static function init() {
        set_exception_handler(array('Core_Exceptionhandler', 'handleException'));
    }

    /**
     * Method to handle the exception
     *
     * @param Exception $e Exception
     * @return Boolean Returns true if successful
     */
    public static function handleException($e) {
        if (defined('CONFIG_EXCEPTION_LOG_ENABLED') && CONFIG_EXCEPTION_LOG_ENABLED === true) {
            if ($e instanceof Exception) {
                restore_exception_handler();

                $log = '';
                $log .= "\n###############################################################################\n";
                $log .= '# ' . strftime('%Y-%m-%d %H:%M:%S') . "                                                         #\n";
                $log .= "###############################################################################\n";
                $log .= 'Exception: ' . get_class($e) . "\n";
                $log .= 'Thrown in: ' . str_replace(CONFIG_PATH_SYSTEM, '', $e->getFile()) . '::' . $e->getLine() . "\n";
                $log .= 'Message: ';
                $log .= str_replace("\n", "\n           ", $e->getMessage()) . "\n";
                $log .= 'Remote Address: ' . $_SERVER['REMOTE_ADDR'] . "\n";
                $log .= "Backtrace:\n" . self::formatTrace($e->getTrace()) . "\n";
                if (isset($e->specialtext)) {
                    $log .= $e->specialtext;
                    $log .= "\n";
                }
                if (defined('CONFIG_EXCEPTION_LOG_FILE') && $fp = fopen(CONFIG_EXCEPTION_LOG_FILE, 'a+')) {
                    fwrite($fp, $log);
                    fclose($fp);
                }
            }
        } else {
            return true;
        }
    }

    /**
     *
     * @param array $trace
     * @return string trace as string
     */
    public static function formatTrace($trace) {
        $trace_str = '';
        $steps = count($trace) - 1;
        foreach ($trace AS $k => $step) {
            if (($k == $steps) || (isset($step['type']) && ($step['class'] == 'Core_Exceptionhandler' || $step['class'] == 'Core_Exception'))) {
                continue;
            }
            $trace_str .= "\t" . str_replace(CFG_PATH_SYSTEM, '', $step['file']) . '::' . $step['line'] . ' # ';
            if (isset($step['type'])) {
                $trace_str .= $step['class'] . $step['type'] . $step['function'];
            } else {
                $trace_str .= $step['function'];
            }

            $trace_str .= '(';
            if (is_array($step['args'])) {
                foreach ($step['args'] AS $i => $arg) {
                    if ($i != 0)
                        $trace_str .= ', ';
                    switch (gettype($arg)) {
                        case 'boolean': $trace_str .= ( $arg ? 'true' : false);
                            break;
                        case 'NULL': $trace_str .= 'NULL';
                            break;
                        case 'integer':
                        case 'double': $trace_str .= $arg;
                            break;
                        case 'object': $trace_str .= get_class($arg);
                            break;
                        case 'string': {
                                $value = str_replace(array("\n", "\t", '  '), '', print_r($arg, true));
                                if (strlen($value) < 50) {
                                    $trace_str .= '"' . $value . '"';
                                } else {
                                    $trace_str .= '"' . substr($value, 0, 50) . ' ..."';
                                }
                                break;
                            }
                        default: {
                                $trace_str .= gettype($arg);
                                if (count($arg)) {
                                    $trace_str .= '(' . @count($arg) . ')';
                                }
                            }
                    }
                }
            }
            $trace_str .= ')';
            $trace_str .= "\n";
        }
        return $trace_str;
    }

}

?>
